﻿using System.Diagnostics.CodeAnalysis;
using System.IO;
using Communication.StreamResource;
using Communication.StreamResource.SerialPortImplementation;
using Communication.StreamResource.TCPImplementation;
using Microsoft.Extensions.Logging;

namespace Communication;

/// <summary>
///     流资源工厂类，用于根据配置信息创建不同类型的流资源
/// </summary>
/// <param name="factory">日志记录器工厂接口，用于创建日志记录器</param>
public class StreamResourceFactory(ILoggerFactory factory)
{
    /// <summary>
    ///     根据配置信息创建对应的流资源
    /// </summary>
    /// <param name="info">配置信息，包含创建流资源所需的各种参数</param>
    /// <param name="stream">输出参数，用于返回创建的流资源对象</param>
    /// <returns>创建成功返回true，失败返回false</returns>
    public bool Creation(IConfiguration info, [NotNullWhen(true)] out IStreamResource? stream)
    {
        // 创建特定于IStreamResource的日志记录器
        var logger = factory.CreateLogger(Path.Combine(nameof(IStreamResource), info.ToString(null, null)));

        // 根据配置类型创建对应的流资源
        switch (info.Type)
        {
            case ConfigurationType.Com:
                // 如果配置信息是串口配置，则创建串口流资源
                if (info is SerialPortConfiguration serialPort)
                    return CreationSerialPortStreamResource(serialPort, logger, out stream);
                break;

            case ConfigurationType.Tcp:
                // 如果配置信息是TCP配置，则创建TCP流资源
                if (info is TcpConfiguration tcpPort) return CreationTcpStreamResource(tcpPort, logger, out stream);
                break;

            case ConfigurationType.None:
            default:
                // 不支持的配置类型，不做任何处理
                break;
        }

        // 创建失败，设置stream为null并返回false
        stream = null;
        return false;
    }

    /// <summary>
    ///     创建串口流资源
    /// </summary>
    /// <param name="info">串口配置信息</param>
    /// <param name="logger">日志记录器</param>
    /// <param name="stream">输出参数，用于返回创建的串口流资源对象</param>
    /// <returns>创建成功返回true，失败返回false</returns>
    private static bool CreationSerialPortStreamResource(SerialPortConfiguration info, ILogger logger,
        [NotNullWhen(true)] out IStreamResource? stream)

    {
        // 创建并返回串口流资源对象
        stream = new SerialPortStreamResource(info, logger);
        return true;
    }

    /// <summary>
    ///     创建TCP流资源
    /// </summary>
    /// <param name="info">TCP配置信息</param>
    /// <param name="logger">日志记录器</param>
    /// <param name="stream">输出参数，用于返回创建的TCP流资源对象</param>
    /// <returns>创建成功返回true，失败返回false</returns>
    private static bool CreationTcpStreamResource(TcpConfiguration info, ILogger logger,
        [NotNullWhen(true)] out IStreamResource? stream)

    {
        // 创建并返回TCP流资源对象
        stream = new TcpClientStreamResource(info, logger);
        return true;
    }
}